package pl.model.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import pl.model.dao.AbstractDao;

@Transactional
public class JpaAbstractDao<T> extends JpaDaoSupport implements AbstractDao<T> {

	protected final Log log = LogFactory.getLog(getClass());

	private Class<T> persistentClass;

	public JpaAbstractDao() {
		super();
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		
	}

	@Override
	public void save(T object) {
		persist(object);
	}

	public void persist(T object) {
		getJpaTemplate().persist(object);
		flush();
	}

	@Override
	public T merge(T object) {
		T ret = getJpaTemplate().merge(object);
		flush();
		return ret;
	}

	public T find(int id) {
		return getJpaTemplate().find(persistentClass, id);
	}

	public void remove(T object) {
		getJpaTemplate().remove(object);
		flush();
	}

	public void delete(T object) {
		remove(object);
	}

	public void remove(int id) {
		T object = find(id);
		getJpaTemplate().remove(object);
		flush();
	}

	public List<T> getAll() {
		List<T> list = getJpaTemplate().executeFind(new JpaCallback() {
			@Override
			public Object doInJpa(EntityManager em) throws PersistenceException {
				return em.createQuery("from " + persistentClass.getName()).getResultList();
			}
		});
		return list;
	}

	@Override
	public void flush() {
		getJpaTemplate().flush();

	}
	
	public JpaTemplate getJpaTemplate2(){
		log.debug("zwraca " + this.getJpaTemplate());
		return this.getJpaTemplate();
	}
}
